﻿namespace ReadLineParser.Core;

using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;

/// <summary>
/// Класс, содержащий логику лексического и синтаксического анализа
/// </summary>
public static class SyntacticAnalyzer
{
    /// <summary>
    /// Регулярное выражение для имени переменной
    /// </summary>
    private const String VariableNamePattern = @"^[a-zA-Z_]\w*$";

    /// <summary>
    /// Возможные типы переменной для получения результата Console.ReadLine() в строковом формате
    /// </summary>
    private static readonly IList<String> AvailableVariableTypes = new List<String>()
    {
        "String",
        "string",
        "String?",
        "string?"
    };

    /// <summary>
    /// Статический анализ. Работа с состояниями
    /// </summary>
    /// <param name="tokens"></param>
    /// <returns></returns>
    public static Boolean Analyze(List<String> tokens)
    {
        var state = 0;
        foreach (var token in tokens)
        {
            switch (state)
            {
                case 0:
                    if (token == "var" || AvailableVariableTypes.Contains(token))
                        state = 1;
                    else if (token == "Console")
                        state = 4;
                    else
                        return false;
                    break;
                case 1:
                    if (Regex.IsMatch(token, VariableNamePattern))
                        state = 2;
                    else
                        return false;
                    break;
                case 2:
                    if (token == "=")
                        state = 3;
                    else
                        return false;
                    break;
                case 3:
                    if (token == "Console")
                        state = 4;
                    else
                        return false;
                    break;
                case 4:
                    if (token == ".")
                        state = 5;
                    else
                        return false;
                    break;
                case 5:
                    if (token == "ReadLine")
                        state = 6;
                    else
                        return false;
                    break;
                case 6:
                    if (token == "(")
                        state = 7;
                    else
                        return false;
                    break;
                case 7:
                    if (token == ")")
                        state = 8;
                    else
                        return false;
                    break;
                case 8:
                    return token == ";";
            }
        }

        return false;
    }
}